<?php
namespace lock\redis\factory;

class Scene extends Base
{
    /**
     * @var array 唯一值
     */
    protected $value = [];
    /**
     * Notes:
     * Author: xiayuer<397072174@qq.com>
     * DateTime: 2022/5/8 14:40
     * @param $scene string 场景
     * @param $expire int 过期时间
     * @param $retry int 执行次数
     * @param $sleep int 等待时间
     */
    public function lock($scene,$expire=5,$retry=5,$sleep=10000){
        $bool = false;
        while($retry-- > 0) {
            //生成唯一值
            $value = session_create_id();
            //生成锁
            if($bool = $this->redis->set($scene, $value, ["NX", "EX" => $expire])){
                $this->value[$scene] = $value;
                //注册一个函数在程序结束前执行
                register_shutdown_function(function ()use($scene){
                    $this->unlock($scene);
                });
                break;
            }
//            echo "尝试获取锁".PHP_EOL;
            //休眠
            usleep($sleep);
        }
        return $bool;
    }

    /**
     * Notes:
     * Author: xiayuer<397072174@qq.com>
     * DateTime: 2022/5/8 17:20
     * @param $scene
     * @return false
     */
    public function unlock($scene){
        $script = <<<LUA
        local key=KEYS[1]
        local value=ARGV[1]
        if(redis.call('get','key') == value)
        then
        return redis.call('del',key)
        end
LUA;

        //只能删除自己的锁
        if(isset($this->value[$scene])){
            //当前请求记录的值
            $value = $this->value[$scene];
//            //判断当前请求记录的值和数据库redis中的值是否一致
//            if($value == $this->redis->get($scene)){
//                return $this->redis->del($scene);
//            }
           return  $this->redis->eval($script,[$scene,$value]);
        }
        return false;
    }
}